package cn.zwx.goods.svc.rpc;

import cn.zwx.base.entity.ResponseEntity;
import cn.zwx.base.exception.BizWrapException;
import cn.zwx.base.utils.PageUtil;
import cn.zwx.base.utils.ValidationUtils;
import cn.zwx.goods.svc.constans.GoodsConstans;
import cn.zwx.goods.svc.domain.bo.BrandBO;
import cn.zwx.goods.svc.domain.entity.BrandEntity;
import cn.zwx.goods.svc.domain.entity.CategoryBrandEntity;
import cn.zwx.goods.svc.domain.entity.CategoryEntity;
import cn.zwx.goods.svc.domain.enums.DelFlag;
import cn.zwx.goods.svc.domain.enums.GoodsCodeEnum;
import cn.zwx.goods.svc.rpc.dto.*;
import cn.zwx.goods.svc.rpc.facade.DubboBrandService;
import cn.zwx.goods.svc.rpc.vo.BrandInfoVO;
import cn.zwx.goods.svc.rpc.vo.BrandVO;
import cn.zwx.goods.svc.rpc.vo.CategoryInfoVO;
import cn.zwx.goods.svc.rpc.vo.InsertBrandVO;
import cn.zwx.goods.svc.service.BrandService;
import cn.zwx.goods.svc.service.CategoryBrandService;
import cn.zwx.goods.svc.utils.PinYinUtil;
import cn.zwx.goods.svc.warp.ExceptionWrap;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.apidocs.annotations.ApiDoc;
import org.apache.dubbo.apidocs.annotations.ApiModule;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zhangwenxue
 */
@Service
@ApiModule(value = "品牌相关接口", apiInterface = DubboBrandService.class)
@DubboService(version = "v1.0.0",interfaceClass = DubboBrandService.class,timeout = 8000)
public class DubboBrandServiceImpl implements DubboBrandService {

    public static final Logger logger = LoggerFactory.getLogger(DubboBrandServiceImpl.class);
    @Resource
    private BrandService brandService;

    @Resource
    private CategoryBrandService categoryBrandService;


    @Override
    @ApiDoc(value = "分页查询品牌列表接口")
    public ResponseEntity<PageUtil<BrandVO>> selectPageList(BrandPageListDTO dto) throws BizWrapException {
        // 1.验证参数
        ValidationUtils.getInstance().validate(dto);
        // 2.select count
        PageUtil<BrandVO> returnPage = new PageUtil<>(dto.getPageNum(),dto.getPageSize(), GoodsConstans.INT_0,new ArrayList<>());
        LambdaQueryWrapper<BrandEntity> queryBrandWrapper = new LambdaQueryWrapper<>();
        queryBrandWrapper.like(StringUtils.isNotBlank(dto.getBrandName()),BrandEntity::getName,dto.getBrandName());
        queryBrandWrapper.eq(BrandEntity::getDelFlag, DelFlag.normal.getCode());
        queryBrandWrapper.orderByAsc(BrandEntity::getInitial);
        queryBrandWrapper.orderByAsc(BrandEntity::getSort);
        Integer selectCount = brandService.selectCount(queryBrandWrapper);
        if (selectCount.equals(GoodsConstans.INT_0)){
            return ResponseEntity.success(returnPage);
        }
        // 3.查询数据
        // 3.1计算分页
        Integer startIndex = dto.getPageNum().equals(GoodsConstans.INT_1)?GoodsConstans.INT_0:
                Math.subtractExact(dto.getPageNum(),1) * dto.getPageSize();
        final BrandBO brandBO = new BrandBO();
        brandBO.setPageSize(dto.getPageSize());
        brandBO.setStartIndex(startIndex);
        brandBO.setNameLike(dto.getBrandName());
        List<BrandEntity> selectList = brandService.selectList(brandBO);
        // 4.返回值封装
        if (CollectionUtils.isEmpty(selectList)){
            return ResponseEntity.success(returnPage);
        }
        List<BrandVO> returnList = new ArrayList<>();
        selectList.forEach(t-> {
            final BrandVO brandVO = new BrandVO();
            BeanUtils.copyProperties(t,brandVO);
            returnList.add(brandVO);
        });
        return ResponseEntity.success(new PageUtil<>(dto.getPageSize(), dto.getPageNum(), selectCount, returnList));
    }

    @Override
    @ApiDoc(value = "根据类目Id查询品牌列表借口")
    public ResponseEntity<List<BrandVO>> selectListByCategoryId(BrandCategoryDTO dto) throws BizWrapException {
        // 1.验证参数
        ValidationUtils.getInstance().validate(dto);
        // 2.查询类目下面的品牌信息
        List<BrandEntity> brandEntityList = categoryBrandService.selectListByCategoryId(dto.getCategoryId());
        // 3.返回参数
        List<BrandVO> returnList = new ArrayList<>();
        if (CollectionUtils.isEmpty(brandEntityList)){
            return ResponseEntity.success(returnList);
        }
        brandEntityList.forEach(brandEntity -> {
            BrandVO brandVO = new BrandVO();
            BeanUtils.copyProperties(brandEntity,brandVO);
            returnList.add(brandVO);
        });
        return ResponseEntity.success(returnList);
    }

    @Override
    @ApiDoc(value = "根据品牌id品牌信息接口")
    public ResponseEntity<BrandInfoVO> selectByInfo(BrandInfoDTO dto) throws BizWrapException {
        // 1.验证参数
        ValidationUtils.getInstance().validate(dto);
        // 2.查询品牌信息
        BrandEntity brandEntity = brandService.selectById(dto.getBrandId());
        if (ObjectUtils.isEmpty(brandEntity)){
            logger.error("未查询到品牌信息,请求参数：{}",dto.getBrandId());
            throw ExceptionWrap.wrap(GoodsCodeEnum.BRAND_INFO_NOT_EXIST_ERROR);
        }
        // 3.查询所属类型信息
        List<CategoryEntity> categoryList = categoryBrandService.selectCategoryByBrandId(dto.getBrandId());
        // 4.返回参数
        return ResponseEntity.success(this.packageBrandIndoVO(categoryList));
    }

    @Override
    @ApiDoc(value = "新增品牌接口")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<InsertBrandVO> insertBrand(InsertBrandDTO dto) throws BizWrapException {
        // 1.校验参数
        ValidationUtils.getInstance().validate(dto);
        // 2.判断是否存在
        LambdaQueryWrapper<BrandEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BrandEntity::getName,dto.getName());
        queryWrapper.eq(BrandEntity::getDelFlag, DelFlag.normal.getCode());
        Integer selectCount = brandService.selectCount(queryWrapper);
        if (selectCount > GoodsConstans.INT_0){
            throw  ExceptionWrap.wrap(GoodsCodeEnum.BRAND_INFO_EXIST_ERROR);
        }
        // 3.保存类目信息
        BrandEntity brandEntity = new BrandEntity();
        brandEntity.setSort(dto.getSort());
        brandEntity.setName(dto.getName());
        String yinHeadChar = PinYinUtil.getPinYinHeadChar(dto.getName().substring(GoodsConstans.INT_0
                , GoodsConstans.INT_1));
        brandEntity.setInitial(yinHeadChar);
        brandEntity.setImage(dto.getImage());
        brandService.insert(brandEntity);
        CategoryBrandEntity categoryBrandEntity = new CategoryBrandEntity();
        categoryBrandEntity.setBrandId(brandEntity.getId());
        categoryBrandEntity.setCategoryId(dto.getCategoryId());
        categoryBrandService.insert(categoryBrandEntity);
        // 4.返回参数
        return ResponseEntity.success(new InsertBrandVO(brandEntity.getId()));
    }

    @Override
    @ApiDoc(value = "修改品牌接口")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<Void> modifyBrand(ModifyBrandDTO dto) throws BizWrapException {
        // 1.验证参数
        ValidationUtils.getInstance().validate(dto);
        // 2.查询是否存在
        LambdaQueryWrapper<BrandEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BrandEntity::getName,dto.getName());
        queryWrapper.ne(BrandEntity::getId,dto.getBrandId());
        queryWrapper.eq(BrandEntity::getDelFlag, DelFlag.normal.getCode());
        Integer selectCount = brandService.selectCount(queryWrapper);
        if (selectCount > GoodsConstans.INT_0){
            throw  ExceptionWrap.wrap(GoodsCodeEnum.BRAND_NAME_EXIST_ERROR);
        }
        BrandEntity brandEntity = brandService.selectById(dto.getBrandId());
        if (ObjectUtils.isEmpty(brandEntity)){
            throw ExceptionWrap.wrap(GoodsCodeEnum.BRAND_INFO_NOT_EXIST_ERROR);
        }
        // 3.修改品牌信息
        BrandEntity modify = new BrandEntity();
        modify.setId(dto.getBrandId());
        modify.setName(dto.getName());
        if (StringUtils.isNotBlank(dto.getName())){
            String yinHeadChar = PinYinUtil.getPinYinHeadChar(dto.getName().substring(GoodsConstans.INT_0
                    , GoodsConstans.INT_1));
            modify.setInitial(yinHeadChar);
        }
        modify.setSort(dto.getSort());
        modify.setImage(dto.getImage());
        brandService.update(modify);
        if (ObjectUtils.isEmpty(dto.getCategoryId())){
            return ResponseEntity.success();
        }
        int deleteRow = categoryBrandService.delete(dto.getCategoryId(), modify.getId());
        logger.info("deleteRow:{}",deleteRow);
        CategoryBrandEntity categoryBrandEntity = new CategoryBrandEntity();
        categoryBrandEntity.setCategoryId(dto.getCategoryId());
        categoryBrandEntity.setBrandId(dto.getBrandId());
        categoryBrandService.insert(categoryBrandEntity);
        return ResponseEntity.success();
    }

    @Override
    @ApiDoc(value = "删除品牌接口")
    public ResponseEntity<Void> delBrand(DeleteBrandDTO dto) throws BizWrapException {
        // 1.验证参数
        ValidationUtils.getInstance().validate(dto);
        // 2.验证品牌是否存在
        BrandEntity brandEntity = brandService.selectById(dto.getBrandId());
        if (ObjectUtils.isEmpty(brandEntity)){
            throw ExceptionWrap.wrap(GoodsCodeEnum.BRAND_INFO_NOT_EXIST_ERROR);
        }
        // 3.删除信息
        brandService.delete(dto.getBrandId());
        categoryBrandService.delete(dto.getBrandId());
        return ResponseEntity.success();
    }

    private  BrandInfoVO packageBrandIndoVO(List<CategoryEntity> categoryList) {
        final BrandInfoVO brandInfoVO = new BrandInfoVO();
        brandInfoVO.setId(brandInfoVO.getId());
        brandInfoVO.setImage(brandInfoVO.getImage());
        brandInfoVO.setSort(brandInfoVO.getSort());
        brandInfoVO.setInitial(brandInfoVO.getInitial());
        brandInfoVO.setName(brandInfoVO.getName());
        final List<CategoryInfoVO> categoryInfoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(categoryList)){
            categoryList.forEach(t->{
                final CategoryInfoVO categoryInfoVO = new CategoryInfoVO();
                categoryInfoVO.setId(t.getId());
                categoryInfoVO.setName(t.getName());
                categoryInfoVO.setParentId(t.getParentId());
                categoryInfoVO.setSort(t.getSort());
                categoryInfoList.add(categoryInfoVO);
            });
        }
        brandInfoVO.setCategoryList(categoryInfoList);
        return brandInfoVO;
    }
}
